package com.tomtop.core.dorequest;

import java.lang.reflect.Type;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;

import com.tomtop.core.cache.CacheService;
import com.tomtop.core.cache.impl.DefaultCacheServiceImpl;
import com.tomtop.core.exception.GlobalException;
import com.tomtop.core.exception.GlobalExceptionStatus;
import com.tomtop.core.logging.RunTimeLog;
import com.tomtop.core.utils.JSONUtils;

@Aspect
@Order(7)
@Component
public class HttpRequestAop {
	private final static Logger LOGGER = LoggerFactory.getLogger(HttpRequestAop.class);

	@Autowired HttpRequestHandle httpRequestHandle;
	@Autowired(required = false) CacheService cacheService = new DefaultCacheServiceImpl();

	@Pointcut("@annotation(com.tomtop.core.dorequest.DoHttpRequest)")
	public void httpRequest() {
	}

	@Around(value = "httpRequest()", argNames = "point")
	public Object recordHttp(ProceedingJoinPoint point) throws Throwable {
		LOGGER.debug("HttpRequest代理请求");

		Object[] args = point.getArgs();
		DoHttpRequestData requestData = AnnotationAnalysis.initMethodParameter(point);
		if ((!requestData.isCache()) || requestData.getMethod() != HttpMethod.GET)
			return this.doHttpRequest(point, requestData, args);
		return cacheService.goCache(requestData.getMethodKey(), args, requestData.getCachetimeout(),
				() -> this.doHttpRequest(point, requestData, args));
	}

	private Object doHttpRequest(ProceedingJoinPoint point, DoHttpRequestData requestData, Object[] args)
			throws Throwable {

		RunTimeLog.log("执行开始  方法:{} ", requestData.getMethodKey());
		HttpContext httpContext = httpRequestHandle.handle(requestData, args);
		RunTimeLog.log("执行结束  方法:{} 响应的数据:{}", requestData.getMethodKey(), HttpContext.getResponse());
		try {
			if (requestData.isManuallyprocessed())
				return point.proceed();
			return this.autoReturn(requestData.getReturnType());
		} finally {
			httpContext.close();
		}
	}

	private Object autoReturn(Type returnType) {
		try {
			String relust = HttpContext.getBody();
			if (returnType.getTypeName().equals(String.class.getName()))
				return relust;
			return JSONUtils.fromObject(relust, returnType);
		} catch (Exception e) {
			LOGGER.error("发请求，结果集转化为json失败");
			throw new GlobalException(GlobalExceptionStatus.DO_REQUEST_DESERIALIZATION_FAIL, e);
		}
	}

}
